package com.junzhiit.nengji.api.service.impl;

import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.bainaeco.framework.util.EncryptMD5Util;
import com.junzhiit.nengji.api.service.AuthorizeService;
import com.junzhiit.nengji.api.web.exception.EmailIsExistException;
import com.junzhiit.nengji.api.web.exception.MobilePhoneCodeErrorException;
import com.junzhiit.nengji.api.web.exception.MobilePhoneCodeTimeoutException;
import com.junzhiit.nengji.api.web.exception.MobilePhoneHasUsedException;
import com.junzhiit.nengji.api.web.exception.RegisteredFailureException;
import com.junzhiit.nengji.api.web.exception.RoleNotFoundException;
import com.junzhiit.nengji.api.web.exception.SetMealNotFoundException;
import com.junzhiit.nengji.api.web.exception.ShopsLocatedNotFoundException;
import com.junzhiit.nengji.api.web.exception.SystemUserNotFoundException;
import com.junzhiit.nengji.api.web.exception.UserNotFoundException;
import com.junzhiit.nengji.api.web.util.Constants;
import com.junzhiit.nengji.api.web.util.FileUtil;
import com.junzhiit.nengji.api.web.util.OrderNumberUtils;
import com.junzhiit.nengji.api.web.util.RequestUtil;
import com.junzhiit.nengji.api.web.util.tools.NumberUtils;
import com.junzhiit.nengji.api.web.util.wechat.WeChatUtils;
import com.junzhiit.nengji.api.web.util.wechat.bean.OrderInfo;
import com.junzhiit.nengji.api.web.util.wechat.bean.PayParam;
import com.junzhiit.nengji.api.web.vo.PhoneCodeVO;
import com.junzhiit.nengji.api.web.vo.RegistVO;
import com.junzhiit.nengji.api.web.vo.RegisterBaseinfoVO;
import com.junzhiit.nengji.api.web.vo.RegisterShopVO;
import com.junzhiit.nengji.api.web.vo.ResultVO;
import com.junzhiit.nengji.api.web.vo.UserVO;
import com.junzhiit.nengji.bo.ShopLocatedBO;
import com.junzhiit.nengji.bo.UserBO;
import com.junzhiit.nengji.dao.IndustryDAO;
import com.junzhiit.nengji.dao.RoleDAO;
import com.junzhiit.nengji.dao.SetMealDAO;
import com.junzhiit.nengji.dao.ShopDAO;
import com.junzhiit.nengji.dao.ShopInfoDAO;
import com.junzhiit.nengji.dao.ShopsLocatedDAO;
import com.junzhiit.nengji.dao.ShopsLocatedIntegralDAO;
import com.junzhiit.nengji.dao.SystemConfigDAO;
import com.junzhiit.nengji.dao.SystemUserDAO;
import com.junzhiit.nengji.dao.SystemUserRoleDAO;
import com.junzhiit.nengji.dao.UserDAO;
import com.junzhiit.nengji.dao.cache.ShopCacheDAO;
import com.junzhiit.nengji.dao.cache.SystemUserCacheDAO;
import com.junzhiit.nengji.dao.util.DIYKey;
import com.junzhiit.nengji.model.Role;
import com.junzhiit.nengji.model.SetMeal;
import com.junzhiit.nengji.model.Shop;
import com.junzhiit.nengji.model.ShopInfo;
import com.junzhiit.nengji.model.ShopsLocated;
import com.junzhiit.nengji.model.ShopsLocatedIntegral;
import com.junzhiit.nengji.model.SystemConfig;
import com.junzhiit.nengji.model.SystemUser;
import com.junzhiit.nengji.model.SystemUserRole;
import com.junzhiit.nengji.model.User;
import com.junzhiit.nengji.model.enums.DefaultType;
import com.junzhiit.nengji.model.enums.Is;
import com.junzhiit.nengji.model.enums.RegistStatus;
import com.junzhiit.nengji.model.enums.ShopStatus;
import com.junzhiit.nengji.model.enums.SystemUserStatus;
import com.junzhiit.nengji.model.enums.SystemUserType;

@Service
public class AuthorizeServiceImpl extends BaseServiceImpl implements AuthorizeService {

	@Value("${key.private}")
	private String PRIVATE_KEY_PATH;

	@Autowired
	private SystemUserDAO systemUserDAO;

	@Autowired
	private UserDAO userDAO;

	@Autowired
	private SystemUserCacheDAO systemUserCacheDAO;

	@Autowired
	private ShopDAO shopDAO;

	@Autowired
	private ShopInfoDAO shopInfoDAO;

	@Autowired
	private IndustryDAO industryDAO;

	@Autowired
	private ShopsLocatedDAO shopsLocatedDAO;

	@Autowired
	private SetMealDAO setMealDAO;

	@Autowired
	private SystemUserRoleDAO systemUserRoleDAO;

	@Autowired
	private RoleDAO roleDAO;

	@Autowired
	private ShopCacheDAO shopCacheDAO;

	@Autowired
	private ShopsLocatedIntegralDAO shopsLocatedIntegralDAO;
	
	@Autowired
	private SystemConfigDAO systemConfigDAO;
	
	@Value("${upload.temp}")
	private String uploadPath;

	@Value("${upload.mall.shop.info}")
	private String shopInfoPath;

	private final String WECHAT_BODY_KEY = "乐鸽订单";


	@Override
	public ResultVO getRegisterSetMeal() {
		ResultVO result = new ResultVO();
		SetMeal setMeal = new SetMeal();
		setMeal.setType(Is.NO.toIntValue());
		setMeal.setIsOpenFree(Is.NO.toIntValue());
		result.setData(setMealDAO.getSetMealList(setMeal));
		return result;
	}
	
	@Override
	public ResultVO getRegisterSetMealByFree(Integer isOpenFree) {
		ResultVO result = new ResultVO();
		SetMeal setMeal = new SetMeal();
		setMeal.setIsOpenFree(isOpenFree);
		result.setData(setMealDAO.getSetMealList(setMeal));
		return result;
	}

	@Override
	@Transactional
	public ResultVO registerSetMeal(HttpServletRequest request, RegistVO registVO) {
		ResultVO result = new ResultVO();
		User user = userDAO.query(registVO.getUserId());
		if (user == null) {
			throw new UserNotFoundException("用户没找到！");
		}
		SetMeal setMeal = setMealDAO.query(registVO.getSetMealId());
		if (setMeal == null) {
			throw new SetMealNotFoundException("套餐没找到！");
		}

		// 插入用户入驻商家记录
		String orderNumber = NumberUtils.getOrderlNumber();
		ShopsLocated shopsLocated = new ShopsLocated();
		shopsLocated.setUserId(registVO.getUserId());
		shopsLocated.setSetMealId(registVO.getSetMealId());
		shopsLocated.setNumber(orderNumber);
		shopsLocated.setUserCode(registVO.getUserCode());
		shopsLocated.setPayMoney(Double.valueOf(registVO.getPayMoney()));
		shopsLocated.setPayWay(registVO.getPayWay());
		shopsLocated.setRegistStatus(RegistStatus.INDUSTRY.toIntStatus());
		shopsLocated.setUserName(registVO.getUserName());
		shopsLocated.setMobilePhone(registVO.getMobilePhone());
		shopsLocated.setShopName(registVO.getShopName());
		shopsLocated.setAddress(registVO.getAddress());
		ShopsLocated param = shopsLocatedDAO.insert(shopsLocated);

		if(StringUtils.isNoneBlank(registVO.getUserCode())){
			SystemConfig systemConfig = systemConfigDAO.find();
			if(systemConfig.getIsOpenShopLocatedIntegral() == Is.YES.toIntValue()){
				User parentUser = userDAO.getUserByCode(registVO.getUserCode());
				ShopsLocatedIntegral shopsLocatedIntegral = new ShopsLocatedIntegral();
				shopsLocatedIntegral.setShopsLocatedId(param.getId());
				shopsLocatedIntegral.setUserId(registVO.getUserId());
				shopsLocatedIntegral.setUserName(registVO.getUserName());
				shopsLocatedIntegral.setPayMoney(registVO.getPayMoney());
				shopsLocatedIntegral.setInviterId(parentUser.getId());
				shopsLocatedIntegral.setInviterName(parentUser.getNickName());
				shopsLocatedIntegral.setInviterIntegralRatio(systemConfig.getShopLocatedIntegral());
			
				shopsLocatedIntegral.setReturnIntegral(registVO.getPayMoney() * systemConfig.getShopLocatedIntegral() /100);
				shopsLocatedIntegral.setStatus(Is.NO.toIntValue());
				shopsLocatedIntegralDAO.insert(shopsLocatedIntegral);
			}
		}
		
		// 微信支付
		OrderInfo orderInfo = new OrderInfo();
		orderInfo.setAttach(Constants.WECHAT_ATTACH_FOR_SHIASD);
		orderInfo.setOutTradeNo(orderNumber);
		orderInfo.setBody(WECHAT_BODY_KEY + "-" + orderNumber);
		orderInfo.setTotalFee(Math.round(param.getPayMoney() * 100));
		orderInfo.setSpbillCreateIp(RequestUtil.getRealIp(request));
		orderInfo.setOpenId(user.getOpenId());
		orderInfo.setTradeType(registVO.getTradeType());
		PayParam payParam = WeChatUtils.getPayParam(orderInfo);

		Map<String, Object> map = new HashMap<String, Object>();
		map.put("shopsLocatedNumber", param.getNumber());
		map.put("shopsLocatedId", param.getId());
		map.put("patParam", payParam);
		result.setData(map);
		return result;
	}

	@Override
	public ResultVO registerPayFailure(String shopsLocatedId) {
		ResultVO result = new ResultVO();
		if (StringUtils.isNotBlank(shopsLocatedId)) {
			ShopsLocatedIntegral locatedIntegral = shopsLocatedIntegralDAO.getShopsLocatedIntegral(shopsLocatedId);
			if(locatedIntegral != null){
				shopsLocatedIntegralDAO.updateToDelete(locatedIntegral.getId());
			}
			result.setData(shopsLocatedDAO.updateToDelete(shopsLocatedId));
		}
		return result;
	}

	@Override
	@Transactional
	public ResultVO register(RegisterBaseinfoVO registerBaseinfoVO) {
		ResultVO result = new ResultVO();
		String mobilePhone = registerBaseinfoVO.getMobilePhone();
		String password = registerBaseinfoVO.getPassword();
		String code = registerBaseinfoVO.getCode();
		String name = registerBaseinfoVO.getName();
		String email = registerBaseinfoVO.getEmail();
		PhoneCodeVO phoneCode = systemUserCacheDAO.getHash(DIYKey.getMobilePhoneCodeKey(mobilePhone),
				PhoneCodeVO.class);

		// 验证码不一致
		if (!phoneCode.getCode().equals(code)) {
			throw new MobilePhoneCodeErrorException("验证码不一致");
		}
		if (phoneCode.getTimestamp() < new Date().getTime()) {
			throw new MobilePhoneCodeTimeoutException("验证码已过期");
		}

		// 判断是否有入驻记录
		ShopsLocated shopsLocated = shopsLocatedDAO.fingById(registerBaseinfoVO.getShopsLocatedId());
		if (shopsLocated == null) {
			throw new ShopsLocatedNotFoundException("未找到入驻记录");
		}

		// 已存在手机号码
		int count = systemUserDAO.getMobilePhoneCount(mobilePhone);
		if (count > 0) {
			throw new MobilePhoneHasUsedException("手机号码已存在,请登录！");
		}

		// 已存在邮箱
		int countEmail = systemUserDAO.checkEmail(email);
		if (countEmail > 0) {
			throw new EmailIsExistException("邮箱已存在");
		}

		SystemUser systemUser = new SystemUser();
		String MD5password = EncryptMD5Util.getMD5(password);
		systemUser.setPassword(MD5password);
		systemUser.setMobilePhone(mobilePhone);
		systemUser.setName(name);
		systemUser.setIsMainAccount(Is.YES.toIntValue());
		systemUser.setGender(registerBaseinfoVO.getGender());
		systemUser.setEmail(email);
		systemUser.setPlatform(SystemUserType.SHOP.toIntStatus());
		systemUser.setStatus(SystemUserStatus.ACTIVE.toIntStatus());
		systemUser.setIsAuth(Is.NO.toIntValue());
		systemUser.setIsUpdatePassword(Is.NO.toIntValue());
		systemUser.setSafetyLevel(0);
		systemUser.setShopsLocatedId(shopsLocated.getId());
		systemUser.setRegiestStatus(RegistStatus.BASE.toIntStatus());
		systemUser.setShopsLocatedId(registerBaseinfoVO.getShopsLocatedId());
		systemUser.setIsImproveMeal(Is.YES.toIntValue());
		SystemUser user = systemUserDAO.insert(systemUser);

		// 注册失败
		if (user == null) {
			throw new RegisteredFailureException("注册失败");
		}

		// 添加商户默认角色
		SystemUserRole systemUserRole = new SystemUserRole();
		systemUserRole.setSystemUserId(user.getId());
		Role role = roleDAO.getDefaultRole(DefaultType.SHOP.toIntStatus());
		if (role == null) {
			throw new RoleNotFoundException("默认角色不存在");
		}
		systemUserRole.setRoleId(role.getId());
		systemUserRoleDAO.insert(systemUserRole);

		// 修改入驻记录的入驻步骤
		shopsLocated.setRegistStatus(RegistStatus.BASE.toIntStatus());
		shopsLocated.setUpdatedTime(new Date());
		shopsLocatedDAO.update(shopsLocated);

		Map<String, Object> map = new HashMap<String, Object>();
		map.put("systemUserId", user.getId());
		map.put("shopsLocatedId", shopsLocated.getId());
		result.setData(map);
		return result;
	}

	@Override
	public ResultVO registerIndustry(String parentId) {
		ResultVO result = new ResultVO();
		result.setData(industryDAO.getIndustryFullName(parentId));
		return result;
	}

	@Override
	public ResultVO registerShopAdd(RegisterShopVO registerShopVO) {
		ResultVO result = new ResultVO();
		ShopsLocated shopsLocated = shopsLocatedDAO.fingById(registerShopVO.getShopsLocatedId());
		if (shopsLocated == null) {
			throw new ShopsLocatedNotFoundException("未找到入驻记录");
		}
		SystemUser systemUser = systemUserDAO.query(registerShopVO.getSystemUserId());
		if (systemUser == null) {
			throw new SystemUserNotFoundException("找不到用户");
		}
		
		String userId="root";
		if(StringUtils.isNotBlank(shopsLocated.getUserCode())){
			User user=userDAO.getUserByCode(shopsLocated.getUserCode());
			if(user!=null){
				userId = user.getId();
			}
		}

		try {
			Shop shop = new Shop();
			BeanUtils.copyProperties(registerShopVO, shop);
			shop.setUserId(userId);
			Long index = shopCacheDAO.incr(DIYKey.getShopCodeStringKey());
			String code = OrderNumberUtils.getSystemCode(OrderNumberUtils.SHOP_NUMBER_PREFIX, index.intValue());
			shop.setCode(code);
			shop.setMainAccountId(registerShopVO.getSystemUserId());
			shop.setStatus(ShopStatus.STOP.toIntStatus());
			shop.setIsSetType(Is.NO.toIntValue());
			shop.setSetMealId(shopsLocated.getSetMealId());
			Shop param = shopDAO.insert(shop);

			if (param == null) {
				throw new RegisteredFailureException("注册失败！");
			}

			// 更新systemUser表
			systemUser.setSystemId(param.getId());
			systemUser.setRegiestStatus(RegistStatus.INDUSTRY.toIntStatus());
			systemUser.setIsImproveShop(Is.YES.toIntValue());
			systemUserDAO.update(systemUser);
			
			// 插入shopInfo表
			ShopInfo shopInfo = new ShopInfo();
			shopInfo.setShopId(shop.getId());
			ShopInfo info = shopInfoDAO.insert(shopInfo);

			// 修改入驻记录的入驻步骤
			shopsLocated.setRegistStatus(RegistStatus.SHOP.toIntStatus());
			shopsLocated.setShopId(param.getId());
			shopsLocated.setUpdatedTime(new Date());
			if(StringUtils.isNotBlank(param.getName())){
				shopsLocated.setShopName(param.getName());
			}
			if(StringUtils.isNotBlank(param.getAddress())){
				shopsLocated.setAddress(param.getAddress());
			}
			shopsLocatedDAO.update(shopsLocated);

			Map<String, Object> map = new HashMap<String, Object>();
			map.put("shopsLocatedId", shopsLocated.getId());
			map.put("shopId", shop.getId());
			map.put("shopInfoId", info.getId());
			result.setData(map);
		} catch (Exception e) {
			throw new RegisteredFailureException("注册失败！");
		}
		return result;
	}

	@Override
	public ResultVO registerChecked(String userId,String userCode) {
		ResultVO result = new ResultVO();
		UserBO userBO = userDAO.getUserById(userId);
		if (userBO == null) {
			throw new UserNotFoundException("User not found.");
		}
		Map<String, Object> map = new HashMap<String, Object>();
		ShopLocatedBO shopsLocated = shopsLocatedDAO.findByUserId(userId);
		if (shopsLocated != null) {
			map.put("registStatus", shopsLocated.getRegistStatus());
			map.put("shopsLocatedId", shopsLocated.getId());
			map.put("setMealName", shopsLocated.getSetMealName());
			map.put("isOpenFree", shopsLocated.getIsOpenFree());
			if(shopsLocated.getRegistStatus()==RegistStatus.BASE.toIntStatus()){
				SystemUser systemUser=systemUserDAO.findByShopsLocatedId(shopsLocated.getId());
				map.put("systemUserId", systemUser.getId());	
			}else if(shopsLocated.getRegistStatus()==RegistStatus.SHOP.toIntStatus()){
				ShopInfo shopInfo=shopInfoDAO.findByShopId(shopsLocated.getShopId());
				map.put("shopInfoId", shopInfo.getId());
			}
			if(StringUtils.isNotBlank(shopsLocated.getUserCode())){
				userCode = shopsLocated.getUserCode();
			}
		}
		UserVO userVO = new UserVO();
		if(StringUtils.isNotBlank(userCode)){
			User reUser = userDAO.getUserByCode(userCode);
			BeanUtils.copyProperties(reUser, userVO);
			userVO.setHeadImgUrl(reUser.getAvatarUrl());
		}else{
			BeanUtils.copyProperties(userBO, userVO);
		}
		map.put("user", userVO);
		result.setData(map);
		return result;
	}

	@Override
	public ResultVO registerComplet(RegisterShopVO registerShopVO) {
		ResultVO result = new ResultVO();
		ShopsLocated shopsLocated = shopsLocatedDAO.fingById(registerShopVO.getShopsLocatedId());
		if (shopsLocated == null) {
			throw new ShopsLocatedNotFoundException("未找到入驻记录");
		}

		// 上传图片
		if (StringUtils.isNotBlank(registerShopVO.getIdentityImgUrl())) {
			FileUtil.moveFile(uploadPath + registerShopVO.getIdentityImgUrl(), shopInfoPath);
		}
		if (StringUtils.isNotBlank(registerShopVO.getIdentityBackImgUrl())) {
			FileUtil.moveFile(uploadPath + registerShopVO.getIdentityBackImgUrl(), shopInfoPath);
		}
		if (StringUtils.isNotBlank(registerShopVO.getIdentityFrontImgUrl())) {
			FileUtil.moveFile(uploadPath + registerShopVO.getIdentityFrontImgUrl(), shopInfoPath);
		}
		if (StringUtils.isNotBlank(registerShopVO.getSubjectImgUrl())) {
			FileUtil.moveFile(uploadPath + registerShopVO.getSubjectImgUrl(), shopInfoPath);
		}

		// 修改shopInfo表
		ShopInfo shopInfo = shopInfoDAO.query(registerShopVO.getShopInfoId());
		BeanUtils.copyProperties(registerShopVO, shopInfo);
		shopInfo.setUpdatedTime(new Date());
		shopInfoDAO.update(shopInfo);

		if (shopInfo.getIdentityType() != null && shopInfo.getSubjectType() != null
				&& StringUtils.isNotBlank(shopInfo.getIdentityName())
				&& StringUtils.isNotBlank(shopInfo.getIdentityCode())
				&& StringUtils.isNotBlank(shopInfo.getIdentityBackImgUrl())
				&& StringUtils.isNotBlank(shopInfo.getIdentityFrontImgUrl())
				&& StringUtils.isNotBlank(shopInfo.getIdentityImgUrl())
				&& StringUtils.isNotBlank(shopInfo.getLegalPerson())
				&& StringUtils.isNotBlank(shopInfo.getRegistrationAddress())
				&& StringUtils.isNotBlank(shopInfo.getUnitName())
				&& StringUtils.isNotBlank(shopInfo.getSubjectImgUrl())) {

			// 修改入驻记录的入驻步骤
			shopsLocated.setRegistStatus(RegistStatus.SHOPINFO.toIntStatus());
			shopsLocated.setUpdatedTime(new Date());
			shopsLocatedDAO.update(shopsLocated);
		}

		return result;
	}

}
